package com.yangmf.auto_message_handle.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 文档解析工具类 - 支持多种文档格式
 * 支持: .doc, .docx, .xls, .xlsx, .txt, .csv
 */
@Slf4j
@Component
public class DocumentParserUtil {

    /**
     * 解析文档内容（自动检测类型）
     * @param fileBytes 文件字节数组
     * @param fileName 文件名（用于判断类型）
     * @return 文档文本内容
     */
    public String parseDocument(byte[] fileBytes, String fileName) {
        if (fileBytes == null || fileBytes.length == 0) {
            return "文件内容为空";
        }

        try {
            String extension = getFileExtension(fileName).toLowerCase();
            log.info("开始解析文档: {}, 类型: {}, 大小: {} bytes", fileName, extension, fileBytes.length);

            switch (extension) {
                case "docx":
                    return parseDocx(fileBytes);
                case "doc":
                    return parseDoc(fileBytes);
                case "xlsx":
                    return parseXlsx(fileBytes);
                case "xls":
                    return parseXls(fileBytes);
                case "txt":
                    return parseText(fileBytes);
                case "csv":
                    return parseCsv(fileBytes);
                default:
                    log.warn("不支持的文件类型: {}", extension);
                    return "不支持的文件类型: " + extension + "\n" + getSupportedFileTypes();
            }
        } catch (Exception e) {
            log.error("文档解析失败: {}", e.getMessage(), e);
            return "文档解析失败: " + e.getMessage();
        }
    }

    /**
     * 解析 Word 2007+ 文档 (.docx)
     */
    private String parseDocx(byte[] fileBytes) throws IOException {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(fileBytes);
             XWPFDocument document = new XWPFDocument(bis);
             XWPFWordExtractor extractor = new XWPFWordExtractor(document)) {
            
            String content = extractor.getText().trim();
            log.info("DOCX文档解析成功，字符数: {}", content.length());
            return content;
        }
    }

    /**
     * 解析 Word 97-2003 文档 (.doc)
     */
    private String parseDoc(byte[] fileBytes) throws IOException {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(fileBytes);
             POIFSFileSystem fileSystem = new POIFSFileSystem(bis);
             HWPFDocument document = new HWPFDocument(fileSystem);
             WordExtractor extractor = new WordExtractor(document)) {
            
            String content = extractor.getText().trim();
            log.info("DOC文档解析成功，字符数: {}", content.length());
            return content;
        }
    }

    /**
     * 解析 Excel 2007+ 文档 (.xlsx)
     */
    private String parseXlsx(byte[] fileBytes) throws IOException {
        return parseExcelWorkbook(fileBytes, "XLSX");
    }

    /**
     * 解析 Excel 97-2003 文档 (.xls)
     */
    private String parseXls(byte[] fileBytes) throws IOException {
        return parseExcelWorkbook(fileBytes, "XLS");
    }

    /**
     * 通用 Excel 解析方法
     */
    private String parseExcelWorkbook(byte[] fileBytes, String format) throws IOException {
        StringBuilder content = new StringBuilder();
        DataFormatter formatter = new DataFormatter();
        
        try (ByteArrayInputStream bis = new ByteArrayInputStream(fileBytes);
             Workbook workbook = new XSSFWorkbook(bis)) {
            
            int sheetCount = workbook.getNumberOfSheets();
            log.info("{}文档包含 {} 个工作表", format, sheetCount);
            
            for (int i = 0; i < sheetCount; i++) {
                Sheet sheet = workbook.getSheetAt(i);
                String sheetName = sheet.getSheetName();
                content.append("=== 工作表 ").append(i + 1).append(": ").append(sheetName).append(" ===\n");
                
                int rowCount = 0;
                int maxColumns = 0;
                
                for (Row row : sheet) {
                    StringBuilder rowContent = new StringBuilder();
                    int columnCount = 0;
                    
                    for (Cell cell : row) {
                        String cellValue = formatter.formatCellValue(cell);
                        rowContent.append("[").append(cellValue).append("] ");
                        columnCount++;
                    }
                    
                    if (columnCount > maxColumns) {
                        maxColumns = columnCount;
                    }
                    
                    if (rowContent.length() > 0) {
                        content.append("行").append(row.getRowNum() + 1).append(": ");
                        content.append(rowContent.toString().trim()).append("\n");
                        rowCount++;
                    }
                }
                
                content.append("【本工作表共 ").append(rowCount).append(" 行数据，最大列数: ").append(maxColumns).append("】\n\n");
            }
            
            log.info("{}文档解析成功，总字符数: {}", format, content.length());
            return content.toString().trim();
        }
    }

    /**
     * 解析文本文件
     */
    private String parseText(byte[] fileBytes) {
        String content = new String(fileBytes, StandardCharsets.UTF_8).trim();
        log.info("文本文件解析成功，字符数: {}", content.length());
        return content;
    }

    /**
     * 解析 CSV 文件
     */
    private String parseCsv(byte[] fileBytes) {
        String content = new String(fileBytes, StandardCharsets.UTF_8);
        StringBuilder formattedContent = new StringBuilder();
        
        String[] lines = content.split("\n");
        log.info("CSV文件包含 {} 行数据", lines.length);
        
        for (int i = 0; i < lines.length; i++) {
            String line = lines[i].trim();
            if (!line.isEmpty()) {
                String[] columns = line.split(",");
                formattedContent.append("行").append(i + 1).append(": ");
                for (int j = 0; j < columns.length; j++) {
                    formattedContent.append("[")
                                   .append(columns[j].trim())
                                   .append("] ");
                }
                formattedContent.append("\n");
            }
        }
        
        log.info("CSV文件解析成功，字符数: {}", formattedContent.length());
        return formattedContent.toString().trim();
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        if (fileName == null || fileName.isEmpty()) {
            return "unknown";
        }
        int lastDotIndex = fileName.lastIndexOf(".");
        return lastDotIndex > 0 ? fileName.substring(lastDotIndex + 1) : "";
    }

    /**
     * 检查是否支持的文件类型
     */
    public boolean isSupportedFileType(String fileName) {
        String extension = getFileExtension(fileName).toLowerCase();
        return extension.matches("docx?|xlsx?|xls|txt|csv");
    }

    /**
     * 获取支持的文件类型描述
     */
    public String getSupportedFileTypes() {
        return "支持的文件类型:\n" +
               "- Word文档: .doc, .docx\n" +
               "- Excel文档: .xls, .xlsx\n" +
               "- 文本文件: .txt, .csv";
    }

    /**
     * 获取文件类型信息
     */
    public String getFileInfo(byte[] fileBytes, String fileName) {
        String extension = getFileExtension(fileName).toLowerCase();
        return String.format("文件信息:\n- 文件名: %s\n- 类型: %s\n- 大小: %d bytes\n- 支持解析: %s",
                fileName, extension, fileBytes.length, isSupportedFileType(fileName) ? "是" : "否");
    }
}